﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using CalculatorLogic.Basic_Math;
using CalculatorLogic.Exponentiation;
using CalculatorLogic.Trignometric_Math;
using CalculatorLogic.Logarithmic_Math;

namespace CalculatorLogic
{
     public class PostfixSolver
    {
        public string Solve(string postfixExp, Equation equation)
        {
            Stack<string> stack = new Stack<string>();
            TokenHelper tokenHelper = new TokenHelper();

            Addition addition = new Addition();
            Subtraction subtraction = new Subtraction();
            Multiplication multiplication = new Multiplication();
            Division division = new Division();
            Power power = new Power();
            Sine sin = new Sine();
            Cosine cos = new Cosine();
            Tangent tan = new Tangent();
            Cotangent cot = new Cotangent();
            Cosecant csc = new Cosecant();
            Secant sec = new Secant();
            NaturalLog ln = new NaturalLog();
            Log log = new Log();
            
            string temp;

            string[] expression = postfixExp.Split(' ');

            foreach (string currentToken in expression)
            {
                if (tokenHelper.IsNumber(currentToken))
                {
                    stack.Push(currentToken);
                }
                
                if (currentToken == "+")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    equation.Input[0] = temp;
                    equation.Input[1] = stack.Peek();

                    addition.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "-")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    equation.Input[0] = temp;
                    try
                    {
                        equation.Input[1] = stack.Peek();
                        stack.Pop();
                    }
                    catch
                    {
                        equation.Input[1] = "0";
                    }

                    subtraction.Apply(equation);                    
                    stack.Push(equation.Solved);
                }

                if (currentToken == "*")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    equation.Input[0] = temp;
                    equation.Input[1] = stack.Peek();

                    multiplication.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "/")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    equation.Input[0] = temp;
                    equation.Input[1] = stack.Peek();

                    division.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "^")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    equation.Input[0] = temp;
                    equation.Input[1] = stack.Peek();

                    power.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "SIN")
                {
                    equation.Input[0] = stack.Peek();
                    sin.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "COS")
                {
                    equation.Input[0] = stack.Peek();
                    cos.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "TAN")
                {
                    equation.Input[0] = stack.Peek();
                    tan.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "COT")
                {
                    equation.Input[0] = stack.Peek();
                    cot.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "CSC")
                {
                    equation.Input[0] = stack.Peek();
                    csc.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "SEC")
                {
                    equation.Input[0] = stack.Peek();
                    sec.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "LN")
                {
                    equation.Input[0] = stack.Peek();
                    ln.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

                if (currentToken == "LOG")
                {
                    equation.Input[0] = stack.Peek();
                    log.Apply(equation);

                    stack.Pop();
                    stack.Push(equation.Solved);
                }

            }
            if (stack.Count > 0)
            {
                equation.LastAnswers.Add(equation.Solved);
                return stack.Peek();
            }
            else
            {
                return "0";
            }
        }

    }
}
